/*
 * Killocan 2013
 * http://killocan.blogspot.com
*/

#include "scenesoundmanager.h"
#include <stdio.h>

SceneSoundManager::SceneSoundManager(const std::string & fileName)
  : data(NULL), mp3_handle(NULL), mp3_data(NULL), curDataOk(false)
{
  if (fileName.find(".dat") != std::string::npos)
  {
    data = load_datafile(fileName.c_str());
  }
  else
  {
    int data_len = 0;

    PACKFILE * mp3_file = pack_fopen(fileName.c_str(), F_READ);
    if (mp3_file != NULL)
    {
      data_len = file_size_ex(fileName.c_str());
      mp3_data = (unsigned char *) malloc(sizeof(unsigned char) * data_len);

      if ((data_len = pack_fread(mp3_data, data_len, mp3_file)) > 0)
      {
        mp3_handle = almp3_create_mp3(mp3_data, data_len);
      }

      pack_fclose(mp3_file);
    }
  }

  if (data != NULL || mp3_data != NULL)
  {
	  curDataOk = true;
  }
  else
  {
	  curDataOk = false;
  }
}

SceneSoundManager::~SceneSoundManager()
{
  if (data != NULL)
  {
  	stop_midi();
    unload_datafile(data);
  }
  else if (mp3_data != NULL)
  {
    almp3_stop_autopoll_mp3(mp3_handle);
    almp3_destroy_mp3(mp3_handle);
    free(mp3_data);
  }
}

void SceneSoundManager::play(int soundId, bool loop)
{
  // VOLUME 0..245. Since sfx are played a little louder
  static const int VOLUME = 120;
	if (curDataOk == true)
	{
    if (data != NULL)
    {
  	  switch(data[soundId].type)
  	  {
  		case DAT_SAMPLE:
  		{
        SAMPLE * sample = static_cast<SAMPLE *>(data[soundId].dat);
        play_sample(sample, VOLUME+10, 128, 1000, (int)loop);
  		}
  		break;
  		case DAT_MIDI:
  		{
  	    MIDI * midi = static_cast<MIDI *>(data[soundId].dat);
  	    play_midi(midi, loop);
  	  }
  	  break;
  	  }
    }
    else if (mp3_data != NULL && soundId == 0)
    {
      almp3_rewind_mp3(mp3_handle);
      almp3_play_ex_mp3(mp3_handle, (1<<16), VOLUME, 128, 1000, (int) loop);
      almp3_start_autopoll_mp3(mp3_handle, 100);
    }
  }
}

bool SceneSoundManager::isPlaying()
{
  if (mp3_data)
  {
    return (almp3_is_playing_mp3(mp3_handle) == TRUE);
  }

  return false;
}

void SceneSoundManager::stopSample(int soundId)
{
  if (curDataOk == true)
  {
    if (data != NULL)
    {
      SAMPLE * sample = static_cast<SAMPLE *>(data[soundId].dat);
      stop_sample(sample);
    }
  }
}

void SceneSoundManager::stopAll()
{
  if (data != NULL)
  {
  	stop_midi();
  }
  else if (mp3_data)
  {
    almp3_rewind_mp3(mp3_handle);
    almp3_stop_autopoll_mp3(mp3_handle);
    almp3_stop_mp3(mp3_handle);
  }
}
